#include"faad.h"
#include"SDLPlayer.h"
#include<stdio.h>
#include<SDL\SDL.h>
typedef struct _Packet{
char*data;
int  len;
struct _Packet*Next;
}Packet;
typedef struct _PacketCache{
Packet*first;
Packet*last;
int  counts;
}PacketCache;
faacDecHandle g_faacd=NULL;
PacketCache g_AudioCache={NULL,NULL,0};
SDL_mutex*g_mutex=NULL;
void PushPacket(const char*data,int len){
Packet*temp=(Packet*)malloc(sizeof(Packet));
temp->data=malloc(len);
temp->len=len;
temp->Next=NULL;
memcpy(temp->data,data,len);
SDL_LockMutex(g_mutex);
if(g_AudioCache.first==NULL){
   g_AudioCache.first=g_AudioCache.last=temp;
}else{
   g_AudioCache.last->Next=temp;
   g_AudioCache.last=temp;
}
g_AudioCache.counts++;
SDL_UnlockMutex(g_mutex);
}
Packet*PopPacket(){
    Packet*temp=NULL;
SDL_LockMutex(g_mutex);
    if(g_AudioCache.first!=NULL){
        temp=g_AudioCache.first;
        g_AudioCache.first=g_AudioCache.first->Next;
        g_AudioCache.counts--;
    }
SDL_UnlockMutex(g_mutex);
    return temp;
}
int  GetAudioCachePackets(){
    int Packets=0;
SDL_LockMutex(g_mutex);
Packets=g_AudioCache.counts;
SDL_UnlockMutex(g_mutex);
    return Packets;
}
static void my_audio_callback(void *userdata, Uint8 *stream, int len){
    Packet*tmp=PopPacket();
    if(tmp!=NULL){
       SDL_MixAudio(stream,tmp->data,len,SDL_MIX_MAXVOLUME);
    }
}
void _InitAudioThread(const char*buffer,int bufferlen){
    faacDecConfigurationPtr faacConf=NULL;
    unsigned long sample=0;
	unsigned char channels=0;
    SDL_AudioSpec wav_spec={0};
    g_mutex=SDL_CreateMutex();
    g_faacd=faacDecOpen();
    faacConf=faacDecGetCurrentConfiguration(g_faacd);
    faacDecSetConfiguration(g_faacd,faacConf);
    faacDecInit(g_faacd,(unsigned char*)buffer,bufferlen,&sample,&channels);
    printf("sample:%d channels:%d\n",sample,channels);

    wav_spec.callback=my_audio_callback;
    wav_spec.freq=sample;
    wav_spec.samples=1024;
    wav_spec.channels=channels;
    wav_spec.format=AUDIO_S16;
    if(SDL_OpenAudio(&wav_spec,NULL)<0){
       printf("OpenAudio Error\n");
    }
    SDL_PauseAudio(0);
}
void _PushAudioPacket(const char*buffer,int bufferlen){
    faacDecFrameInfo info={0};
    char*date=(char*)faacDecDecode(g_faacd,&info,(unsigned char*)buffer,bufferlen);
    if(info.samples>0)PushPacket(date,info.channels*info.samples);
}
void ClearAudioThread(){
    faacDecClose(g_faacd);
    SDL_CloseAudio();
    SDL_DestroyMutex(g_mutex);
}